package com.grid.control;

import com.grid.entity.Mission;
import com.grid.entity.AQI;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class MissionSubmitViewController {

    @FXML private Label lblReporter;
    @FXML private Label lblPhone;
    @FXML private Label lblGrid;
    @FXML private Label lblLocation;
    @FXML private Label lblLevel;
    @FXML private Label lblDescription;
    @FXML private Label lblAQILevel;

    @FXML private TextField txtSO2;
    @FXML private TextField txtCO;
    @FXML private TextField txtPM25;

    private Mission currentMission;
    private static final String AQI_FILE = "AQI.txt";

    public void initData(Mission mission) {
        this.currentMission = mission;
        lblReporter.setText(mission.getReporter());
        lblPhone.setText(mission.getPhone());
        lblGrid.setText(mission.getGrid());
        lblLocation.setText(mission.getLocation());
        lblLevel.setText(mission.getLevel());
        lblDescription.setText(mission.getDescription());

        txtSO2.textProperty().addListener((obs, oldVal, newVal) -> calculateAQI());
        txtCO.textProperty().addListener((obs, oldVal, newVal) -> calculateAQI());
        txtPM25.textProperty().addListener((obs, oldVal, newVal) -> calculateAQI());
    }

    @FXML
    private void handleSubmit() {
        try {
            int so2 = txtSO2.getText().isEmpty() ? 0 : Integer.parseInt(txtSO2.getText());
            int co = txtCO.getText().isEmpty() ? 0 : Integer.parseInt(txtCO.getText());
            int pm25 = txtPM25.getText().isEmpty() ? 0 : Integer.parseInt(txtPM25.getText());
            int year = Integer.parseInt(currentMission.getYear());
            int month = Integer.parseInt(currentMission.getMonth());

            int aqiValue = calculateAQI(so2, co, pm25);
            String level = getAQILevel(aqiValue);

            AQI aqiRecord = new AQI(so2, co, pm25, aqiValue,year,month);

            saveAQIData(aqiRecord);

            lblAQILevel.setText(String.format("AQI等级: %d (%s)", aqiValue, level));
            lblAQILevel.setStyle("-fx-text-fill: #2196F3;");

            System.out.println("提交数据成功: " + currentMission);
            System.out.println("SO2浓度: " + so2 + " μg/m³");
            System.out.println("CO浓度: " + co + " μg/m³");
            System.out.println("PM2.5浓度: " + pm25 + " μg/m³");
            System.out.println("计算AQI: " + aqiValue);

            closeWindow();

        } catch (NumberFormatException e) {
            lblAQILevel.setText("请输入有效数字");
            lblAQILevel.setStyle("-fx-text-fill: red;");
        } catch (IOException e) {
            System.err.println("保存数据失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    private void saveAQIData(AQI newRecord) throws IOException {
        List<AQI> aqiList = loadAQIData();
        aqiList.add(newRecord);

        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(AQI_FILE))) {
            oos.writeObject(aqiList);
        }
    }

    @SuppressWarnings("unchecked")
    private List<AQI> loadAQIData() throws IOException {
        File file = new File(AQI_FILE);
        if (!file.exists() || file.length() == 0) {
            return new ArrayList<>();
        }

        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
            return (List<AQI>) ois.readObject();
        } catch (ClassNotFoundException e) {
            throw new IOException("数据文件格式错误", e);
        }
    }

    private void calculateAQI() {
        try {
            double so2 = txtSO2.getText().isEmpty() ? 0 : Double.parseDouble(txtSO2.getText());
            double co = txtCO.getText().isEmpty() ? 0 : Double.parseDouble(txtCO.getText());
            double pm25 = txtPM25.getText().isEmpty() ? 0 : Double.parseDouble(txtPM25.getText());

            int aqi = calculateAQI(so2, co, pm25);
            String level = getAQILevel(aqi);

            lblAQILevel.setText(String.format("AQI等级: %d (%s)", aqi, level));
            lblAQILevel.setStyle("-fx-text-fill: #2196F3;");

        } catch (NumberFormatException e) {
            lblAQILevel.setText("请输入有效数字");
            lblAQILevel.setStyle("-fx-text-fill: red;");
        }
    }

    private int calculateAQI(double so2, double co, double pm25) {
        int iaqiSO2 = calculateIAQI(so2, new int[]{0, 50, 150, 475, 800, 1600, 2100, 2620});
        int iaqiCO = calculateIAQI(co, new int[]{0, 2, 4, 14, 24, 36, 48, 60});
        int iaqiPM25 = calculateIAQI(pm25, new int[]{0, 35, 75, 115, 150, 250, 350, 500});
        return Math.max(Math.max(iaqiSO2, iaqiCO), iaqiPM25);
    }

    private int calculateIAQI(double c, int[] bp) {
        if (c <= bp[1]) return linearInterp(c, bp[0], bp[1], 0, 50);
        else if (c <= bp[2]) return linearInterp(c, bp[1], bp[2], 50, 100);
        else if (c <= bp[3]) return linearInterp(c, bp[2], bp[3], 100, 150);
        else if (c <= bp[4]) return linearInterp(c, bp[3], bp[4], 150, 200);
        else if (c <= bp[5]) return linearInterp(c, bp[4], bp[5], 200, 300);
        else if (c <= bp[6]) return linearInterp(c, bp[5], bp[6], 300, 400);
        else return c > bp[6] ? 500 : 0;
    }

    private int linearInterp(double c, double cLow, double cHigh, int iLow, int iHigh) {
        return (int) ((iHigh - iLow) / (cHigh - cLow) * (c - cLow) + iLow);
    }

    private String getAQILevel(int aqi) {
        if (aqi <= 50) return "一级 优";
        else if (aqi <= 100) return "二级 良";
        else if (aqi <= 150) return "三级 轻度污染";
        else if (aqi <= 200) return "四级 中度污染";
        else if (aqi <= 300) return "五级 重度污染";
        else return "六级 严重污染";
    }

    @FXML
    private void handleCancel() {
        closeWindow();
    }

    private void closeWindow() {
        Stage stage = (Stage) txtCO.getScene().getWindow();
        stage.close();
    }
}